﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 协变和逆变1
{
    class Program
    {
        public class Person { }
        public class Student : Person { }
        public class Teacher : Person { }
        static void Main(string[] args)
        {
            /// 泛型的协变和逆变 是 C# 4.0 里面出现的新的语法
            /// C# 1.0就有协变和逆变了，只不过是委托的
            /// C# 2.0 添加了泛型 这个东西（解决了代码重用这个问题）
            /// C# 4.0 添加了泛型接口 的协变和逆变。（协变和逆变可以说是泛型的一个补丁）

            ///定义两个类 一个是 人 一个是 学生
            ///学生必然是人
            ///所以 Person p1 = new Student() 是对的
            Person p1 = new Student();
            ///一群学生必然是一群人
            ///但是 List<Person> p2 = new List<Student>(); 是错的

            //List<Person> p2 = new List<Student>();

            ///     从C#语法上来讲是OK的 Person 是 Student 的父类
            ///     但是 List<Person> 不是 List<Student> 的父类
            ///     所以没啥问题
            ///     但是他不符合我们日常的行为逻辑
            ///     所以C# 4.0 就出现了协变和逆变

            //协变
            IEnumerable<Person> p2 = new List<Student>();
            IQueryable<Person> p3 = p2.AsQueryable();
            List<Person> p4 = new List<Person>();
            p4.Add(new Person());
            p4.Add(new Student());
            p4.Add(new Teacher());
            p2 = p4;
            IDemo协变<Person> d1 = new Demo协变<Student>();

            //逆变 和 协变 正好相反
            IDemo逆变<Student> dd1 = new Demo逆变<Person>();

            ///逆变 + 协变
            Func<Student, Person> f1 = (s) =>
            {
                return new Student();
            };

            //逆变
            Action<Student, Student> a1 = (s1, t1) => { };

            ///这玩意一般情况下使用不到的
            

        }
    }

    public interface IDemo协变<out T> { };
    public class Demo协变<T> : IDemo协变<T> { }


    public interface IDemo逆变<in T> { };
    public class Demo逆变<T> : IDemo逆变<T> { }

}
